package org.mx.dal.service;

import java.util.Date;

import org.mx.DigestUtils;
import org.mx.StringUtils;
import org.mx.dal.entity.Base;
import org.mx.dal.entity.BaseDict;
import org.mx.dal.entity.BaseDictTree;
import org.mx.dal.entity.PO;
import org.mx.error.UserInterfaceSystemErrorException;
import org.mx.error.UserInterfaceSystemErrorException.SystemErrors;
import org.mx.spring.session.SessionDataStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

/**
 * 描述： 跨数据库平台的通用数据操作方法
 *
 * @author john peng Date time 2019/3/22 5:22 PM
 */
public abstract class AbstractGeneralAccessor implements GeneralAccessor {
	private static final Logger logger = LoggerFactory.getLogger(AbstractGeneralAccessor.class);

	/**
	 * 会话数据存储
	 */
	protected SessionDataStore sessionDataStore;

	/**
	 * 获取指定的实体在库中的映像
	 *
	 * @param t   实体对象
	 * @param <T> 实体对象泛型定义
	 * @return 如果存在，则返回对应的实体对象，否则返回null。
	 */
	@SuppressWarnings("unchecked")
	protected <T extends PO> T getCheckedEntity(T t) {
		Class<T> clazz = (Class<T>) t.getClass();
		String id = t.getId();
		if (!StringUtils.isBlank(id)) {
			T check = getById(id, clazz);
			if (check != null) {
				return check;
			}
		}
		if (t instanceof BaseDict) {
			String code = ((BaseDict) t).getCode();
			if (!StringUtils.isBlank(code)) {
				T check = findOne(ConditionTuple.eq("code", code), clazz);
				if (check != null) {
					return check;
				}
			} else {
				if (logger.isErrorEnabled()) {
					logger.error(String.format("The Dict object's code is blank, object: %s.", JSON.toJSONString(t)));
				}
				throw new UserInterfaceSystemErrorException(SystemErrors.SYSTEM_ILLEGAL_PARAM);
			}
		}
		return null;
	}

	/**
	 * 判断指定的对象是否已经存在
	 * 
	 * @param <T> 实体对象泛型定义
	 * @param t 实体对象
	 * @return 如果存在，则返回true，否则返回false。
	 */
	protected <T extends PO> boolean checkExist(T t) {
		T old = getCheckedEntity(t);
		return old == null;
	}

	/**
	 * 创建一个有效性判断条件
	 *
	 * @param isValid true表示有效，否则表示无效
	 * @return 有效性判断条件
	 */
	protected ConditionTuple createValidCondition(boolean isValid) {
		return isValid ? ConditionTuple.eq("valid", 1) : null;
	}

	/**
	 * 实体保存前相关处理，包括：创建、修改时间，ID，父子关系等。
	 *
	 * @param t   实体对象
	 * @param <T> 实体对象范型定义
	 * @return 如果存在返回false，不存在返回true。
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected <T extends PO> boolean prepareSave(T t) {
		if (t instanceof Base) {
			Base base = (Base) t;
			if (base.getUpdatedTime() <= 0) {
				// 如果外部传入过修改时间，则以外部传入为准
				base.setUpdatedTime(new Date().getTime());
			}
			if (StringUtils.isBlank(base.getOperator()) || "NA".equalsIgnoreCase(base.getOperator())) {
				base.setOperator(sessionDataStore.getCurrentUserCode());
			}
		}
		Class<T> clazz = (Class<T>) t.getClass();
		if (t instanceof BaseDictTree) {
			if (!StringUtils.isBlank(((BaseDictTree) t).getParentId())) {
				T p = getById(((BaseDictTree) t).getParentId(), clazz);
				((BaseDictTree) t).setParent((BaseDictTree) p);
				((BaseDictTree) t).setLikedCode(((BaseDictTree) p).getLikedCode() + ((BaseDictTree) t).getCode());
			} else {
				((BaseDictTree) t).setLikedCode(((BaseDictTree) t).getCode());
			}
		}
		if (!checkExist(t)) {
			// 新增操作
			if (StringUtils.isBlank(t.getId())) {
				// 如果ID为空，则自动生成UUID，否则使用外部传入的ID
				t.setId(DigestUtils.uuid());
			}
			if (t instanceof Base) {
				Base base = (Base) t;
				if (base.getCreatedTime() <= 0) {
					base.setCreatedTime(new Date().getTime());
				}
			}
			return true;
		} else {
			// 修改操作
			T old = getCheckedEntity(t);
			t.setId(old.getId());
			if (t instanceof Base) {
				((Base) t).setCreatedTime(((Base) old).getCreatedTime());
				if (t instanceof BaseDict) {
					// 代码字段一旦保存，则不允许被修改
					((BaseDict) t).setCode(((BaseDict) old).getCode());
				}
			}
			return false;
		}
	}
}
